<?php

namespace LowCode\Traits;

use LowCode\AutoId;
use LowCode\Support\JsBind;
use LowCode\Support\JsExp;
use LowCode\Support\JsFn;

trait HasProps
{

    /**
     * 设置 props属性
     * @param string $key
     * @param mixed $value
     * @param int $type 0=默认, 1=JSExpression, 2=JSFunction
     * @return $this
     */
    public function prop(string $key, mixed $value, int $type = 0): static
    {
        $props = $this->get("props",[]);
        if ($type == 0 && is_string($value)){
            if (str_starts_with($value,'this.')||str_starts_with($value,'exp:')){
                $value = JsExp::make(ltrim($value,"exp:"));
            }
            if (str_starts_with($value,'fn:')){
                $value = JsFn::make(ltrim($value,"fn:"));
            }
        }
        $props[$key] = match ($type) {
            1 => JsExp::make($value),
            2 => JsFn::make($value),
            default => $value,
        };
        return $this->props($props);
    }

    /**
     * 设置 prop bool值 属性
     * @param string $key
     * @param bool|string|JsExp $bool
     * @return $this
     */
    public function setBoolProp(string $key, bool|string|JsExp $bool = true): static
    {
        $props = $this->get("props",[]);
        if (is_string($bool)){
            $bool = JsExp::make($bool);
        }
        $props[$key] = $bool;
        return $this->props($props);
    }

    /**
     * 设置组件key值
     * @param string|int|array $value
     * @return $this
     */
    public function key(string|int|array $value): static
    {
        return $this->prop("key", $value);
    }

    /**
     * 设置组件key值
     * @param string $value
     * @param string $id
     * @return $this
     */
    public function expKey(string $value, string $id): static
    {
        return $this->jsExpression("key", $value, $id);
    }

    /**
     * 设置组件ref值
     * @param string|JsExp|JsFn $value
     * @return $this
     */
    public function ref(string|JsExp|JsFn $value): static
    {
        return $this->prop("ref", $value);
    }

    /**
     * 设置组件ref值 jsExpression 类型
     * @param string $value
     * @param string|null $id
     * @return $this
     */
    public function expRef(string $value, string $id = null): static
    {
        return $this->jsExpression("ref", $value, $id);
    }

    /**
     * 设置组件 ref 值 jsFunction 类型
     * @param string $value
     * @param string|null $id
     * @return $this
     */
    public function fnRef(string $value, string $id = null): static
    {
        return $this->jsFunction("ref", $value, $id);
    }

    /**
     * 设置组件样式 style
     * @param string $key
     * @param mixed $value
     * @return $this
     */
    public function style(string $key, mixed $value): static
    {
        $props = $this->get("props",[]);
        $style = $props['style']??[];
        $style[$key] = $value;
        return $this->prop("style", $style);
    }

    /**
     * 设置组件样式 style
     * @param array|JsExp $styles
     * @return $this
     */
    public function styles(array|JsExp $styles): static
    {
        if ($styles instanceof JsExp){
            $style = $styles;
        }else{
            $props = $this->get("props",[]);
            $style = $props['style']??[];
            if ($style&&is_array($style)){
                $style = array_merge($style, $styles);
            }
        }
        return $this->prop("style", $style);
    }

    /**
     * 设置组件 class
     * @param string|array|JsExp $value
     * @return $this
     */
    public function class(string|array|JsExp $value): static
    {
        return $this->prop("class", $value);
    }

    /**
     * 设置组件 class jsExpression
     * @param string $value
     * @param string $id
     * @return $this
     */
    public function expClass(string $value, string $id): static
    {
        return $this->jsExpression("class", $value, $id);
    }
}
